package com.alibaba.aliper.agent;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.concurrent.ConcurrentHashMap;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;

import com.alibaba.aliper.agent.jmeter.JmeterParser;
import com.alibaba.aliper.agent.jmeter.ThreadGroupData;
import com.alibaba.aliper.server.interfaces.AliperRemoteControll;
import com.caucho.hessian.client.HessianProxyFactory;


public class JMeterLogClient {
	@Option(name = "-i", usage = "interval. Sampling interval in milliseconds.", required = false)
	private int interval = 1000;
	
	@Option(name = "-jmeter", usage = "jmeter log file.", required = true)
	private File jmeterLogFile = null;
	
	@Option(name = "-server", usage = "server ip or name. default is localhost", required = false)
	private String serverIp = "localhost";
	
	@Option(name = "-port", usage = "server port. default is 8080.", required = false)
	private String port = "8080";
	
	@Option(name = "-project", usage = "project. default is project.", required = false)
	private String project = "project";
	
	private long parsedLines = 0;
	ConcurrentHashMap<String, ThreadGroupData> map = null;
	public synchronized ThreadGroupData getDataOnCreate(String threadName) {
		ThreadGroupData data = null;
		if (map.containsKey(threadName)) {
			data = map.get(threadName);
		} else {
			data = new ThreadGroupData(threadName,this.interval);
			map.put(threadName, data);
		}
		return data;
	}
	public void run() throws InterruptedException, IOException{
		this.parsedLines = jmeterLogFile.length();
		while(true){
			Thread.sleep(this.interval);
			if(jmeterLogFile.exists() && jmeterLogFile.isFile()){
				BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(this.jmeterLogFile)));
				reader.skip(this.parsedLines);
				map = new ConcurrentHashMap<String, ThreadGroupData>();
				String line = "";
				boolean back = false;
				String backLine = "";
				while((line = reader.readLine()) != null){
						ThreadGroupData data = null;
						String res = JmeterParser.getProperty(line, " t");
						String tim =  JmeterParser.getProperty(line, " ts");
						String suc =  JmeterParser.getProperty(line, " s");
						String nam =  JmeterParser.getProperty(line, " tn");
						if(res != null && tim != null && suc != null && nam != null){
						    long response = Long.parseLong(res);
						    long time = Long.parseLong(tim);
							boolean success = "true".equalsIgnoreCase(suc);
							String threadGroupName = nam;
							int lindex = nam.lastIndexOf('-');
							if(lindex >= 0)
								threadGroupName = nam.substring(0, lindex);
							data = getDataOnCreate(threadGroupName);
							data.update(time, success, response);
							this.parsedLines += line.getBytes().length;
							back = false;
						} else {
							back = true;
							backLine = line;
							System.out.println("ingore line:"+line);
						}
				}
				if(back)
					this.parsedLines -= backLine.length();
				sendSamples(map);
			} else {
				System.out.println("jmeter log file "+this.jmeterLogFile + " not exists or not a file");
			}
		}
	}
	private AliperRemoteControll remote = null;
	private void sendSamples(ConcurrentHashMap<String, ThreadGroupData> map2) throws MalformedURLException {
		if(remote == null){
			HessianProxyFactory factory = new HessianProxyFactory();
			remote = (AliperRemoteControll) factory.create(AliperRemoteControll.class, "http://"+this.serverIp+":"+this.port+"/aliper-server/AliperServlet");
		}
		for(String key : map2.keySet()){
			ThreadGroupData data = map2.get(key);
			String resname = data.getName()+"_res";
			String tpsname = data.getName()+"_tps";
			remote.report(project,jmeterLogFile.getName(),resname, "minResponse", data.getMinTime(), data.getMinResponse());
			remote.report(project,jmeterLogFile.getName(),resname, "avgResponse", data.getCloserTime(), data.getAvgResponse());
			remote.report(project,jmeterLogFile.getName(),resname, "maxResponse", data.getMaxTime(), data.getMaxResponse());
			remote.report(project,jmeterLogFile.getName(),tpsname, "tps", data.getMaxTime(), data.getTPS());
		}
	}
	public static void main(String[] args) throws Exception {
		JMeterLogClient client = new JMeterLogClient();
		CmdLineParser cmdLineParser = new CmdLineParser(client);
		try {
			cmdLineParser.parseArgument(args);
		} catch (CmdLineException e) {
			System.err.println(e.getMessage());
			System.out.println("Usage:");
			cmdLineParser.printUsage(System.out);
			return;
		}
		client.run();
	}
}
